package com.aaa.sso.config;

import com.aaa.sso.util.CustomModularRealmAuthenticator;
import com.aaa.sso.util.MemberRealm;
import com.aaa.sso.util.UserRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @fileName:ShiroConfig
 * @description:
 * @author:zhz
 * @createTime:2020/12/7 10:46
 * @version:1.0.0
 */
@Configuration
public class ShiroConfig {

    /**
     * 实例化过滤工厂类（配置拦截路径及放行路径，配置使用SecurityManager等）
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        //实例化
        ShiroFilterFactoryBean shiroFilterFactoryBean = new
                ShiroFilterFactoryBean();
        //配置使用SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager());

        //实例化参数对象（LinkedHashMap 先后配置顺序读取）
        Map<String,String> pathMap = new LinkedHashMap<>();
         //anon  放行  authc  拦截  loginOut 退出。。。
        pathMap.put("/**","anon");
        //配置拦截或者放行路径
        shiroFilterFactoryBean.setFilterChainDefinitionMap(pathMap);
        return shiroFilterFactoryBean;
    }

    /**
     * shiro核心组件   安全管理组件   认证和授权的后台管理类
     * @return
     */
    @Bean
    public SecurityManager securityManager(){
        //实例化 SecurityManager子类，web应用使用
        DefaultWebSecurityManager securityManager =new DefaultWebSecurityManager();
        //设置自定义认证器
        securityManager.setAuthenticator(customModularRealmAuthenticator());
        //设置安全数据链接桥梁   Realm
        //securityManager.setRealm(myRealm());
        List<Realm> realmList = new ArrayList<>();
        realmList.add(memberRealm());
        realmList.add(userRealm());
        securityManager.setRealms(realmList);
        return securityManager;
    }

    /**
     * 设置自定义认证器（认证策略为一个realm成功及成功）
     * @return
     */
    @Bean
    public CustomModularRealmAuthenticator customModularRealmAuthenticator(){
        CustomModularRealmAuthenticator customModularRealmAuthenticator =
                new CustomModularRealmAuthenticator();
        //配置认证策略，两个Realm 只要有一个认证成功，都可以访问资源
        //无论是手机端还是管理端，登录认证后，都可以访问所有资源
        customModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return customModularRealmAuthenticator;
    }

    /**
     * 自定义memberRealm类
     * @return
     */
    @Bean
    public MemberRealm memberRealm(){
        //实例化安全数据链接桥梁
        MemberRealm myRealm =new MemberRealm();
        //设置加密算法类
        myRealm.setCredentialsMatcher(credentialsMatcher());
        return myRealm;
    }

    /**
     * 自定义userRealm类
     * @return
     */
    @Bean
    public UserRealm userRealm(){
        //实例化安全数据链接桥梁
        UserRealm userRealm =new UserRealm();
        //设置加密算法类
        userRealm.setCredentialsMatcher(credentialsMatcher());
        return userRealm;
    }


    /**
     * 加密算法类
     * @return
     */
    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher =
                new HashedCredentialsMatcher();
        //设置加密算法名称
        credentialsMatcher.setHashAlgorithmName("SHA-512");
        //设置hash次数
        credentialsMatcher.setHashIterations(1024);
        return credentialsMatcher;
    }

}
